﻿using Furion.DynamicApiController;
using Furion.JsonSerialization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using OAS.Application.System.Dtos;
using OAS.Application.UserApp.Dtos;
using OAS.Core;
using System;
using System.Net;
using System.Net.Sockets;

namespace OAS.Application;

public class UserController : IDynamicApiController
{
    private readonly ISqlSugarClient db;
    private readonly IMemoryCache _memoryCache;
    private readonly IUserService _userService;
    private readonly IHttpContextAccessor _httpContextAccessor;
    public UserController(IUserService userService, ISqlSugarClient db, 
        IMemoryCache memoryCache,IHttpContextAccessor httpContextAccessor)
    {
        this.db = db;
        _userService = userService;
        _httpContextAccessor = httpContextAccessor;
        _memoryCache = memoryCache;
    }
    [AllowAnonymous]
    public async Task<User> UserLogin(DtoUserLR dto)
    {
        var key = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
        if (!_memoryCache.TryGetValue(key, out var code)) throw Oops.Oh("验证码已过期");
        if (!dto.Code.Equals(code.ToString(), StringComparison.OrdinalIgnoreCase)) throw Oops.Oh("验证码错误");
        var user = await db.Queryable<User>().FirstAsync(o => o.UserName == dto.UserName && o.Password == _userService.MD5Encrypt64(dto.Password)) ?? throw Oops.Oh("用户名或密码错误");
        user.Password = "";
        // 生成 token
        var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>()
            {
                { "UserId", user.User_Id },  // 存储Id
                { "UserName",user.UserName }, // 存储用户名
            });
        // 获取刷新 token
        var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, 43200); // 第二个参数是刷新 token 的有效期（分钟），默认三十天
        // 设置响应报文头
        _httpContextAccessor.HttpContext.Response.Headers["access-token"] = accessToken;
        _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
        return user;
    }
    public void UserLoginOut() { }
    public DtoUserInfo UserInfo(DtoUserLR dto)
    {
        return _userService.GetUserInfo(dto.UserName);
    }
    public async Task UserRegister(DtoUserLR dto)
    {
        User user = dto.Adapt<User>();
        await _userService.AddNewUser(user);
    }
    [HttpGet, NonUnify]
    [AllowAnonymous]
    public IActionResult VerifyCode()
    {
        string code = VerifyCodeHandler.CreateRandomCode(4);
        var key = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
        _memoryCache.Set(key, code, TimeSpan.FromMinutes(1));
        return new FileContentResult(VerifyCodeHandler.CreateBase64Image(code), "image/Jpeg");
    }
    public async Task<List<User>> GetAllUser()
    {
        return await _userService.GetAllUser();
    }
    public async Task<List<User>> GetAllUserByDepartment()
    {
        return await _userService.GetAllUserByDepartment();
    }
    [HttpPost]
    public async Task<object> GetUserList(DtoQuery dto)
    {
        return await _userService.GetUserList(dto);
    }
    public async Task AddUser(User user)
    {
        await _userService.AddNewUser(user);
    }
    public async Task UpdateUser(User user)
    {
        await _userService.UpdateUser(user);
    }
    public async Task DeleteUser([FromBody]string[] ids)
    {
        await _userService.DeleteUser(ids);
    }
    public async Task PasswordChange(DtoPwd dto)
    {
        await _userService.PasswordChange(dto);
    }
}
